home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / netrom.c < prev    next >
C/C++ Source or Header  |  1992-05-14  |  58KB  |  2,249 lines

  1. /* @(#) $Header: netrom.c,v 1.29 92/05/14 13:20:19 deyke Exp $ */
  2.  
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #include "global.h"
  9. #include "config.h"
  10. #include "netuser.h"
  11. #include "mbuf.h"
  12. #include "timer.h"
  13. #include "iface.h"
  14. #include "arp.h"
  15. #include "ip.h"
  16. #include "ax25.h"
  17. #include "lapb.h"
  18. #include "netrom.h"
  19. #include "cmdparse.h"
  20. #include "trace.h"
  21.  
  22. static int  nr_maxdest     =   400;     /* not used */
  23. static int  nr_minqual     =     0;     /* not used */
  24. static int  nr_hfqual      =   192;
  25. static int  nr_rsqual      =   255;     /* not used */
  26. static int  nr_obsinit     =     3;
  27. static int  nr_minobs      =     0;     /* not used */
  28. static int  nr_bdcstint    =  1800;
  29. static int  nr_ttlinit     =    16;
  30. static int  nr_ttimeout    =    60;
  31. static int  nr_tretry      =     5;
  32. static int  nr_tackdelay   =  1900;
  33. static int  nr_tbsydelay   =   180;
  34. static int  nr_twindow     =     8;
  35. static int  nr_tnoackbuf   =     8;
  36. static int  nr_timeout     =  1800;
  37. static int  nr_persistance =    64;     /* not used */
  38. static int  nr_slottime    =    10;     /* not used */
  39. static int  nr_callcheck   =     0;     /* not used */
  40. static int  nr_beacon      =     0;     /* not used */
  41. static int  nr_cq          =     0;     /* not used */
  42.  
  43. static struct parms {
  44.   char  *text;
  45.   int  *valptr;
  46.   int  minval;
  47.   int  maxval;
  48. } parms[] = {
  49.   "",                                               (int *) 0,       0,          0,
  50.   " 1 Maximum destination list entries           ", &nr_maxdest,     1,        400,
  51.   " 2 Worst quality for auto-updates             ", &nr_minqual,     0,        255,
  52.   " 3 Channel 0 (HDLC) quality                   ", &nr_hfqual,      0,        255,
  53.   " 4 Channel 1 (RS232) quality                  ", &nr_rsqual,      0,        255,
  54.   " 5 Obsolescence count initializer (0=off)     ", &nr_obsinit,     0,        255,
  55.   " 6 Obsolescence count min to be broadcast     ", &nr_minobs,      0,        255,
  56.   " 7 Auto-update broadcast interval (sec, 0=off)", &nr_bdcstint,    0,      65535,
  57.   " 8 Network 'time-to-live' initializer         ", &nr_ttlinit,     1,        255,
  58.   " 9 Transport timeout (sec)                    ", &nr_ttimeout,    5,        600,
  59.   "10 Transport maximum tries                    ", &nr_tretry,      1,        127,
  60.   "11 Transport acknowledge delay (ms)           ", &nr_tackdelay,   1,      60000,
  61.   "12 Transport busy delay (sec)                 ", &nr_tbsydelay,   1,       1000,
  62.   "13 Transport requested window size (frames)   ", &nr_twindow,     1,        127,
  63.   "14 Congestion control threshold (frames)      ", &nr_tnoackbuf,   1,        127,
  64.   "15 No-activity timeout (sec, 0=off)           ", &nr_timeout,     0,      65535,
  65.   "16 Persistance                                ", &nr_persistance, 0,        255,
  66.   "17 Slot time (10msec increments)              ", &nr_slottime,    0,        127,
  67.   "18 Link T1 timeout 'FRACK' (ms)               ", &ax_t1init,      1, 0x7fffffff,
  68.   "19 Link TX window size 'MAXFRAME' (frames)    ", &ax_maxframe,    1,          7,
  69.   "20 Link maximum tries (0=forever)             ", &ax_retry,       0,        127,
  70.   "21 Link T2 timeout (ms)                       ", &ax_t2init,      1, 0x7fffffff,
  71.   "22 Link T3 timeout (ms)                       ", &ax_t3init,      0, 0x7fffffff,
  72.   "23 AX.25 digipeating  (0=off 1=dumb 2=s&f)    ", &Digipeat,       0,          2,
  73.   "24 Validate callsigns (0=off 1=on)            ", &nr_callcheck,   0,          1,
  74.   "25 Station ID beacons (0=off 1=after 2=every) ", &nr_beacon,      0,          2,
  75.   "26 CQ UI frames       (0=off 1=on)            ", &nr_cq,          0,          1,
  76. };
  77.  
  78. #define NPARMS 26
  79.  
  80. struct link;
  81.  
  82. static struct node *nodeptr __ARGS((char *call, int create));
  83. static void ax25_state_upcall __ARGS((struct ax25_cb *cp, int oldstate, int newstate));
  84. static void ax25_recv_upcall __ARGS((struct ax25_cb *cp, int cnt));
  85. static void send_packet_to_neighbor __ARGS((struct mbuf *data, struct node *pn));
  86. static void send_broadcast_packet __ARGS((struct mbuf *data));
  87. static void link_manager_initialize __ARGS((void));
  88. static struct linkinfo *linkinfoptr __ARGS((struct node *node1, struct node *node2));
  89. static int update_link __ARGS((struct node *node1, struct node *node2, int source, int quality));
  90. static int link_valid __ARGS((struct node *pn, struct link *pl));
  91. static void calculate_hopcnts __ARGS((struct node *pn));
  92. static void calculate_qualities __ARGS((struct node *pn));
  93. static void calculate_all __ARGS((void));
  94. static void broadcast_recv __ARGS((struct mbuf *bp, struct node *pn));
  95. static struct mbuf *alloc_broadcast_packet __ARGS((void));
  96. static void send_broadcast __ARGS((void));
  97. static void route_packet __ARGS((struct mbuf *bp, struct node *fromneighbor));
  98. static void send_l3_packet __ARGS((char *source, char *dest, int ttl, struct mbuf *data));
  99. static void routing_manager_initialize __ARGS((void));
  100. static void reset_t1 __ARGS((struct circuit *pc));
  101. static void inc_t1 __ARGS((struct circuit *pc));
  102. static int busy __ARGS((struct circuit *pc));
  103. static void send_l4_packet __ARGS((struct circuit *pc, int opcode, struct mbuf *data));
  104. static void try_send __ARGS((struct circuit *pc, int fill_sndq));
  105. static void set_circuit_state __ARGS((struct circuit *pc, int newstate));
  106. static void l4_t1_timeout __ARGS((struct circuit *pc));
  107. static void l4_t2_timeout __ARGS((struct circuit *pc));
  108. static void l4_t3_timeout __ARGS((struct circuit *pc));
  109. static void l4_t4_timeout __ARGS((struct circuit *pc));
  110. static void l4_t5_timeout __ARGS((struct circuit *pc));
  111. static struct circuit *create_circuit __ARGS((void));
  112. static void circuit_manager __ARGS((struct mbuf *bp));
  113. static void nrserv_recv_upcall __ARGS((struct circuit *pc, int cnt));
  114. static void nrserv_send_upcall __ARGS((struct circuit *pc, int cnt));
  115. static void nrserv_state_upcall __ARGS((struct circuit *pc, int oldstate, int newstate));
  116. static void nrclient_parse __ARGS((char *buf, int n));
  117. static void nrclient_state_upcall __ARGS((struct circuit *pc, int oldstate, int newstate));
  118. static int donconnect __ARGS((int argc, char *argv [], void *p));
  119. static int dobroadcast __ARGS((int argc, char *argv [], void *p));
  120. static int doident __ARGS((int argc, char *argv [], void *p));
  121. static int donkick __ARGS((int argc, char *argv [], void *p));
  122. static int dolinks __ARGS((int argc, char *argv [], void *p));
  123. static int donodes __ARGS((int argc, char *argv [], void *p));
  124. static int doparms __ARGS((int argc, char *argv [], void *p));
  125. static int donreset __ARGS((int argc, char *argv [], void *p));
  126. static int donstatus __ARGS((int argc, char *argv [], void *p));
  127.  
  128. /*---------------------------------------------------------------------------*/
  129. /******************************** Link Manager *******************************/
  130. /*---------------------------------------------------------------------------*/
  131.  
  132. #define IDENTLEN     6
  133. #define INFINITY   999
  134.  
  135. struct broadcast {
  136.   struct ax25 hdr;
  137.   struct iface *iface;
  138.   struct broadcast *next;
  139. };
  140.  
  141. struct node {
  142.   char *call;
  143.   char ident[IDENTLEN];
  144.   int hopcnt;
  145.   struct link *links;
  146.   struct node *neighbor, *old_neighbor;
  147.   double quality, old_quality, tmp_quality;
  148.   int force_broadcast;
  149.   struct ax25_cb *crosslink;
  150.   struct node *prev, *next;
  151. };
  152.  
  153. struct ax25_cb *netrom_server_axcb;
  154.  
  155. static struct broadcast *broadcasts;
  156. static struct node *nodes, *mynode;
  157.  
  158. /*---------------------------------------------------------------------------*/
  159.  
  160. static struct node *nodeptr(call, create)
  161. char  *call;
  162. int  create;
  163. {
  164.   struct node *pn;
  165.  
  166.   for (pn = nodes; pn && !addreq(call, pn->call); pn = pn->next) ;
  167.   if (!pn && create) {
  168.     pn = calloc(1, sizeof(*pn));
  169.     pn->call = malloc(AXALEN);
  170.     addrcp(pn->call, call);
  171.     memset(pn->ident, ' ', IDENTLEN);
  172.     pn->hopcnt = INFINITY;
  173.     if (nodes) {
  174.       pn->next = nodes;
  175.       nodes->prev = pn;
  176.     }
  177.     nodes = pn;
  178.   }
  179.   return pn;
  180. }
  181.  
  182. /*---------------------------------------------------------------------------*/
  183.  
  184. static void ax25_state_upcall(cp, oldstate, newstate)
  185. struct ax25_cb *cp;
  186. int  oldstate, newstate;
  187. {
  188.   struct node *pn;
  189.  
  190.   if (cp->user)
  191.     pn = (struct node *) cp->user;
  192.   else
  193.     cp->user = (char *) (pn = nodeptr(cp->hdr.dest, 1));
  194.   switch (newstate) {
  195.   case CONNECTING:
  196.     break;
  197.   case CONNECTED:
  198.     pn->crosslink = cp;
  199.     if (update_link(mynode, pn, 1, nr_hfqual)) calculate_all();
  200.     break;
  201.   case DISCONNECTING:
  202.     if (cp->reason != NORMAL)
  203.       if (update_link(mynode, pn, 1, 0)) calculate_all();
  204.     break;
  205.   case DISCONNECTED:
  206.     pn->crosslink = NULLAXCB;
  207.     if (cp->reason != NORMAL)
  208.       if (update_link(mynode, pn, 1, 0)) calculate_all();
  209.     del_ax(cp);
  210.     break;
  211.   }
  212. }
  213.  
  214. /*---------------------------------------------------------------------------*/
  215.  
  216. static void ax25_recv_upcall(cp, cnt)
  217. struct ax25_cb *cp;
  218. int  cnt;
  219. {
  220.  
  221.   int  pid;
  222.   struct mbuf *bp;
  223.  
  224.   while (cp->rcvq) {
  225.     recv_ax(cp, &bp, 0);
  226.     if ((pid = PULLCHAR(&bp)) == -1) continue;
  227.     if (pid == PID_NETROM)
  228.       nr3_input(bp, cp->hdr.dest);
  229.     else
  230.       free_p(bp);
  231.   }
  232. }
  233.  
  234. /*---------------------------------------------------------------------------*/
  235.  
  236. static void send_packet_to_neighbor(data, pn)
  237. struct mbuf *data;
  238. struct node *pn;
  239. {
  240.  
  241.   char  path[10*AXALEN];
  242.   struct mbuf *bp;
  243.  
  244.   if (!pn->crosslink) {
  245.     addrcp(path, pn->call);
  246.     addrcp(path + AXALEN, Mycall);
  247.     path[AXALEN+6] |= E;
  248.     pn->crosslink = open_ax(path, AX_ACTIVE, ax25_recv_upcall, NULLVFP, ax25_state_upcall, (char *) pn);
  249.     if (!pn->crosslink) {
  250.       if (update_link(mynode, pn, 1, 0)) calculate_all();
  251.       free_p(data);
  252.       return;
  253.     }
  254.     pn->crosslink->mode = DGRAM;
  255.   }
  256.   if (!(bp = pushdown(data, 1))) {
  257.     free_p(data);
  258.     return;
  259.   }
  260.   bp->data[0] = PID_NETROM;
  261.   send_ax(pn->crosslink, bp);
  262. }
  263.  
  264. /*---------------------------------------------------------------------------*/
  265.  
  266. static void send_broadcast_packet(data)
  267. struct mbuf *data;
  268. {
  269.  
  270.   struct broadcast *p;
  271.   struct mbuf *bp, *bp1;
  272.  
  273.   for (p = broadcasts; p; p = p->next) {
  274.     addrcp(p->hdr.source, p->iface->hwaddr);
  275.     dup_p(&bp, data, 0, MAXINT16);
  276.     if (!(bp1 = htonax25(&p->hdr, bp)))
  277.       free_p(bp);
  278.     else if (p->iface->forw)
  279.       (*p->iface->forw->raw)(p->iface->forw, bp1);
  280.     else
  281.       (*p->iface->raw)(p->iface, bp1);
  282.   }
  283.   free_p(data);
  284. }
  285.  
  286. /*---------------------------------------------------------------------------*/
  287.  
  288. static void link_manager_initialize()
  289. {
  290.  
  291.   mynode = nodeptr(Mycall, 1);
  292.   free(mynode->call);
  293.   mynode->call = Mycall;
  294.   calculate_all();
  295.  
  296.   netrom_server_axcb = open_ax(NULLCHAR, AX_SERVER, ax25_recv_upcall, NULLVFP, ax25_state_upcall, NULLCHAR);
  297.   netrom_server_axcb->mode = DGRAM;
  298.  
  299. }
  300.  
  301. /*---------------------------------------------------------------------------*/
  302. /****************************** Routing Manager ******************************/
  303. /*---------------------------------------------------------------------------*/
  304.  
  305. #define NRRTDESTLEN     21              /* length of destination entry in */
  306.                     /* nodes broadcast */
  307. #define PERMANENT       0x7fffffff      /* Max long integer */
  308.  
  309. struct link {
  310.   struct node *node;
  311.   struct linkinfo *info;
  312.   struct link *prev, *next;
  313. };
  314.  
  315. struct linkinfo {
  316.   int  source;
  317.   int  quality;
  318.   long  time;
  319. };
  320.  
  321. struct routes_stat {
  322.   int  rcvd;
  323.   int  sent;
  324. };
  325.  
  326. static struct iface *Nr_iface;
  327. static struct routes_stat routes_stat;
  328. static struct timer broadcast_timer;
  329.  
  330. /*---------------------------------------------------------------------------*/
  331.  
  332. int  isnetrom(call)
  333. char  *call;
  334. {
  335.   return (nodeptr(call, 0) != 0);
  336. }
  337.  
  338. /*---------------------------------------------------------------------------*/
  339.  
  340. static struct linkinfo *linkinfoptr(node1, node2)
  341. struct node *node1, *node2;
  342. {
  343.  
  344.   struct link *pl;
  345.   struct linkinfo *pi;
  346.  
  347.   for (pl = node1->links; pl; pl = pl->next)
  348.     if (pl->node == node2) return pl->info;
  349.   pi = calloc(1, sizeof(*pi));
  350.   pi->source = INFINITY;
  351.   pl = calloc(1, sizeof(*pl));
  352.   pl->node = node2;
  353.   pl->info = pi;
  354.   if (node1->links) {
  355.     pl->next = node1->links;
  356.     node1->links->prev = pl;
  357.   }
  358.   node1->links = pl;
  359.   pl = calloc(1, sizeof(*pl));
  360.   pl->node = node1;
  361.   pl->info = pi;
  362.   if (node2->links) {
  363.     pl->next = node2->links;
  364.     node2->links->prev = pl;
  365.   }
  366.   node2->links = pl;
  367.   return pi;
  368. }
  369.  
  370. /*---------------------------------------------------------------------------*/
  371.  
  372. static int  update_link(node1, node2, source, quality)
  373. struct node *node1, *node2;
  374. int  source, quality;
  375. {
  376.  
  377.   int  ret;
  378.   struct linkinfo *pi;
  379.  
  380.   if (node1 == node2) return 0;
  381.   if (source > node1->hopcnt + 1 || source > node2->hopcnt + 1) return 0;
  382.   pi = linkinfoptr(node1, node2);
  383.   if (source > pi->source || pi->time == PERMANENT) return 0;
  384.   ret = 0;
  385.   if (pi->source != source) {
  386.     pi->source = source;
  387.     ret = 1;
  388.   }
  389.   if (quality > 255) quality = 255;
  390.   if (pi->quality != quality) {
  391.     pi->quality = quality;
  392.     ret = 1;
  393.   }
  394.   pi->time = secclock();
  395.   return ret;
  396. }
  397.  
  398. /*---------------------------------------------------------------------------*/
  399.  
  400. static int link_valid(pn, pl)
  401. struct node *pn;
  402. struct link *pl;
  403. {
  404.   if (pl->info->time == PERMANENT) return 1;
  405.   if (nr_obsinit && nr_bdcstint) {
  406.     if (pl->info->time + nr_obsinit * nr_bdcstint < secclock()) return 0;
  407.   }
  408.   if (pl->info->source > pn->hopcnt + 1) return 0;
  409.   if (pl->info->source > pl->node->hopcnt + 1) return 0;
  410.   return 1;
  411. }
  412.  
  413. /*---------------------------------------------------------------------------*/
  414.  
  415. static void calculate_hopcnts(pn)
  416. struct node *pn;
  417. {
  418.  
  419.   int hopcnt;
  420.   struct link *pl;
  421.  
  422.   hopcnt = pn->hopcnt + 1;
  423.   for (pl = pn->links; pl; pl = pl->next)
  424.     if (link_valid(pn, pl) && pl->node->hopcnt > hopcnt) {
  425.       pl->node->hopcnt = hopcnt;
  426.       calculate_hopcnts(pl->node);
  427.     }
  428. }
  429.  
  430. /*---------------------------------------------------------------------------*/
  431.  
  432. static void calculate_qualities(pn)
  433. struct node *pn;
  434. {
  435.  
  436.   double quality;
  437.   struct link *pl;
  438.  
  439.   for (pl = pn->links; pl; pl = pl->next) {
  440.     quality = pn->tmp_quality * pl->info->quality / 256.0;
  441.     if (pl->node->tmp_quality < quality) {
  442.       pl->node->tmp_quality = quality;
  443.       calculate_qualities(pl->node);
  444.     }
  445.   }
  446. }
  447.  
  448. /*---------------------------------------------------------------------------*/
  449.  
  450. static void calculate_all()
  451. {
  452.  
  453.   int start_broadcast_timer;
  454.   struct link *pl1, *plnext;
  455.   struct link *pl;
  456.   struct node *neighbor;
  457.   struct node *pn1, *pnnext;
  458.   struct node *pn;
  459.  
  460.   /*** preset hopcnt, neighbor, and quality ***/
  461.  
  462.   for (pn = nodes; pn; pn = pn->next) {
  463.     pn->hopcnt = INFINITY;
  464.     pn->old_neighbor = pn->neighbor;
  465.     pn->neighbor = 0;
  466.     pn->old_quality = pn->quality;
  467.     pn->quality = 0.0;
  468.   }
  469.   mynode->hopcnt = 0;
  470.  
  471.   /*** calculate new hopcnts ***/
  472.  
  473.   calculate_hopcnts(mynode);
  474.  
  475.   /*** remove invalid links ***/
  476.  
  477.   for (pn = nodes; pn; pn = pn->next)
  478.     for (pl = pn->links; pl; pl = plnext) {
  479.       plnext = pl->next;
  480.       if (!link_valid(pn, pl)) {
  481.     if (pl->prev)
  482.       pl->prev->next = pl->next;
  483.     else
  484.       pn->links = pl->next;
  485.     if (pl->next) pl->next->prev = pl->prev;
  486.     pn1 = pl->node;
  487.     for (pl1 = pn1->links; pl1->node != pn; pl1 = pl1->next) ;
  488.     if (pl1->prev)
  489.       pl1->prev->next = pl1->next;
  490.     else
  491.       pn1->links = pl1->next;
  492.     if (pl1->next) pl1->next->prev = pl1->prev;
  493.     free(pl->info);
  494.     free(pl1);
  495.     free(pl);
  496.       }
  497.     }
  498.  
  499.   /*** calculate new neighbor and quality values ***/
  500.  
  501.   for (pl = mynode->links; pl; pl = pl->next) {
  502.     for (pn = nodes; pn; pn = pn->next) pn->tmp_quality = 0.0;
  503.     mynode->tmp_quality = 256.0;
  504.     neighbor = pl->node;
  505.     neighbor->tmp_quality = pl->info->quality;
  506.     calculate_qualities(neighbor);
  507.     for (pn = nodes; pn; pn = pn->next)
  508.       if (pn->quality < pn->tmp_quality ||
  509.       pn->quality == pn->tmp_quality && neighbor == pn->old_neighbor) {
  510.     pn->quality = pn->tmp_quality;
  511.     pn->neighbor = neighbor;
  512.       }
  513.   }
  514.   mynode->neighbor = 0;
  515.   mynode->quality = 256.0;
  516.  
  517.   /*** check changes ***/
  518.  
  519.   start_broadcast_timer = 0;
  520.   for (pn = nodes; pn; pn = pn->next) {
  521.     if (pn != mynode &&
  522.     (pn->neighbor != pn->old_neighbor ||
  523.     ((int) pn->quality) != ((int) pn->old_quality)))
  524.       pn->force_broadcast = 1;
  525.     if (pn->force_broadcast) start_broadcast_timer = 1;
  526.   }
  527. #ifdef FORCE_BC
  528.   if (start_broadcast_timer) {
  529.     set_timer(&broadcast_timer, 10 * 1000L);
  530.     start_timer(&broadcast_timer);
  531.   }
  532. #endif
  533.  
  534.   /*** remove obsolete nodes ***/
  535.  
  536.   for (pn = nodes; pn; pn = pnnext) {
  537.     pnnext = pn->next;
  538.     if (pn != mynode && !pn->links && !pn->crosslink && !pn->force_broadcast) {
  539.       if (pn->prev)
  540.     pn->prev->next = pn->next;
  541.       else
  542.     nodes = pn->next;
  543.       if (pn->next) pn->next->prev = pn->prev;
  544.       free(pn->call);
  545.       free(pn);
  546.     }
  547.   }
  548. }
  549.  
  550. /*---------------------------------------------------------------------------*/
  551.  
  552. void new_neighbor(call)
  553. char  *call;
  554. {
  555.   if (update_link(mynode, nodeptr(call, 1), 1, nr_hfqual))
  556.     calculate_all();
  557. }
  558.  
  559. /*---------------------------------------------------------------------------*/
  560.  
  561. static void broadcast_recv(bp, pn)
  562. struct mbuf *bp;
  563. struct node *pn;
  564. {
  565.  
  566.   char  buf[NRRTDESTLEN];
  567.   char  ident[IDENTLEN];
  568.   int  quality;
  569.   struct linkinfo *pi;
  570.   struct node *pb, *pd;
  571.  
  572.   routes_stat.rcvd++;
  573.   if (pn == mynode) goto discard;
  574.   if (PULLCHAR(&bp) != 0xff) goto discard;
  575.   if (pullup(&bp, ident, IDENTLEN) != IDENTLEN) goto discard;
  576.   if (len_p(bp) % NRRTDESTLEN) goto discard;
  577.   if (*ident > ' ') memcpy(pn->ident, ident, IDENTLEN);
  578.   update_link(mynode, pn, 1, nr_hfqual);
  579.   while (pullup(&bp, buf, NRRTDESTLEN) == NRRTDESTLEN) {
  580.     if (ismycall(buf)) continue;
  581.     pd = nodeptr(buf, 1);
  582.     if (buf[AXALEN] > ' ') memcpy(pd->ident, buf + AXALEN, IDENTLEN);
  583.     pb = nodeptr(buf + AXALEN + IDENTLEN, 1);
  584.     quality = uchar(buf[AXALEN+IDENTLEN+AXALEN]);
  585.     if (pb == mynode) {
  586.       if (quality >= pd->quality) pd->force_broadcast = 1;
  587.       continue;
  588.     }
  589.     if (pn == pb || pb == pd)
  590.       update_link(pn, pd, 2, quality);
  591.     else {
  592.       pi = linkinfoptr(pn, pb);
  593.       if (pi->time != PERMANENT) pi->time = secclock();
  594.       if (pi->quality) {
  595.     int  q = quality * 256 / pi->quality;
  596.     while (q * pi->quality / 256 < quality) q++;
  597.     quality = q;
  598.       }
  599.       update_link(pb, pd, 3, quality);
  600.     }
  601.   }
  602.   calculate_all();
  603.  
  604. discard:
  605.   free_p(bp);
  606. }
  607.  
  608. /*---------------------------------------------------------------------------*/
  609.  
  610. static struct mbuf *alloc_broadcast_packet()
  611. {
  612.   struct mbuf *bp;
  613.  
  614.   if (bp = alloc_mbuf(258)) {
  615.     bp->data[0] = UI;
  616.     bp->data[1] = PID_NETROM;
  617.     bp->data[2] = 0xff;
  618.     memcpy(bp->data + 3, mynode->ident, IDENTLEN);
  619.     bp->cnt = 3 + IDENTLEN;
  620.   }
  621.   return bp;
  622. }
  623.  
  624. /*---------------------------------------------------------------------------*/
  625.  
  626. static void send_broadcast()
  627. {
  628.  
  629.   char  *p;
  630.   int  hopcnt, nexthopcnt;
  631.   struct mbuf *bp;
  632.   struct node *pn;
  633.  
  634.   set_timer(&broadcast_timer, nr_bdcstint * 1000L);
  635.   start_timer(&broadcast_timer);
  636.   calculate_all();
  637.   if (!broadcasts) return;
  638.   bp = alloc_broadcast_packet();
  639.   for (hopcnt = 1; hopcnt <= INFINITY; hopcnt = nexthopcnt) {
  640.     nexthopcnt = INFINITY + 1;
  641.     for (pn = nodes; pn; pn = pn->next)
  642.       if (pn->hopcnt >= hopcnt && (((int) pn->quality) || pn->force_broadcast))
  643.     if (pn->hopcnt == hopcnt) {
  644.       pn->force_broadcast = 0;
  645.       if (!bp) bp = alloc_broadcast_packet();
  646.       p = bp->data + bp->cnt;
  647.       addrcp(p, pn->call);
  648.       p += AXALEN;
  649.       memcpy(p, pn->ident, IDENTLEN);
  650.       p += IDENTLEN;
  651.       addrcp(p, pn->neighbor ? pn->neighbor->call : pn->call);
  652.       p += AXALEN;
  653.       *p++ = pn->quality;
  654.       if ((bp->cnt = p - bp->data) > 258 - NRRTDESTLEN) {
  655.         send_broadcast_packet(bp);
  656.         routes_stat.sent++;
  657.         bp = NULLBUF;
  658.       }
  659.     } else if (pn->hopcnt < nexthopcnt)
  660.       nexthopcnt = pn->hopcnt;
  661.   }
  662.   if (bp) {
  663.     send_broadcast_packet(bp);
  664.     routes_stat.sent++;
  665.   }
  666. }
  667.  
  668. /*---------------------------------------------------------------------------*/
  669.  
  670. static void route_packet(bp, fromneighbor)
  671. struct mbuf *bp;
  672. struct node *fromneighbor;
  673. {
  674.  
  675.   int  ttl;
  676.   struct node *pn;
  677.  
  678.   if (!bp || bp->cnt < 15) goto discard;
  679.  
  680.   if (fromneighbor != mynode) {
  681.     if (update_link(mynode, fromneighbor, 1, nr_hfqual)) calculate_all();
  682.     pn = nodeptr(bp->data, 1);
  683.     if (pn == mynode) goto discard;  /* ROUTING ERROR */
  684.     if (!pn->neighbor) {
  685.       struct linkinfo *pi = linkinfoptr(mynode, fromneighbor);
  686.       if (pi->quality) {
  687.     int  q = 1;
  688.     while (q * pi->quality / 256 < 1) q++;
  689.     if (update_link(fromneighbor, pn, 2, q)) calculate_all();
  690.       }
  691.     }
  692.   }
  693.  
  694.   if (ismycall(bp->data + AXALEN)) {
  695.     if (bp->cnt >= 40                     &&
  696.     uchar(bp->data[19]) == 0          &&
  697.     uchar(bp->data[15]) == NRPROTO_IP &&
  698.     uchar(bp->data[16]) == NRPROTO_IP &&
  699.     Nr_iface) {
  700.       Nr_iface->rawrecvcnt++;
  701.       Nr_iface->lastrecv = secclock();
  702.       arp_add(get32(bp->data + 32), ARP_NETROM, bp->data, 0);
  703.       pullup(&bp, NULLCHAR, 20);
  704.       dump(Nr_iface, IF_TRACE_IN, Nr_iface->type, bp);
  705.       ip_route(Nr_iface, bp, 0);
  706.       return;
  707.     }
  708.     pullup(&bp, NULLCHAR, 15);
  709.     if (!bp) return;
  710.     if (fromneighbor == mynode) {
  711.       struct mbuf *hbp = copy_p(bp, len_p(bp));
  712.       free_p(bp);
  713.       bp = hbp;
  714.     }
  715.     circuit_manager(bp);
  716.     return;
  717.   }
  718.  
  719.   ttl = uchar(bp->data[2*AXALEN]);
  720.   if (--ttl <= 0) goto discard;
  721.   bp->data[2*AXALEN] = ttl;
  722.  
  723.   pn = nodeptr(bp->data + AXALEN, 1);
  724.   if (!pn->neighbor) {
  725.     if (fromneighbor != mynode) {
  726.       pn->force_broadcast = 1;
  727. #ifdef FORCE_BC
  728.       send_broadcast();
  729. #endif
  730.     }
  731.     goto discard;
  732.   }
  733.  
  734. #ifdef FORCE_BC
  735.   if (pn->neighbor == fromneighbor ||
  736.       addreq(pn->neighbor->call, bp->data)) send_broadcast();
  737. #endif
  738.  
  739.   send_packet_to_neighbor(bp, pn->neighbor);
  740.   return;
  741.  
  742. discard:
  743.   free_p(bp);
  744. }
  745.  
  746. /*---------------------------------------------------------------------------*/
  747.  
  748. static void send_l3_packet(source, dest, ttl, data)
  749. char  *source, *dest;
  750. int  ttl;
  751. struct mbuf *data;
  752. {
  753.   struct mbuf *bp;
  754.  
  755.   if (!(bp = pushdown(data, 2 * AXALEN + 1))) {
  756.     free_p(data);
  757.     return;
  758.   }
  759.   addrcp(bp->data, source);
  760.   addrcp(bp->data + AXALEN, dest);
  761.   if (++ttl > 255) ttl = 255;
  762.   bp->data[2*AXALEN] = ttl;
  763.   route_packet(bp, mynode);
  764. }
  765.  
  766. /*---------------------------------------------------------------------------*/
  767.  
  768. int nr_send(bp, iface, gateway, prec, del, tput, rel)
  769. struct mbuf *bp;
  770. struct iface *iface;
  771. int32 gateway;
  772. int prec;
  773. int del;
  774. int tput;
  775. int rel;
  776. {
  777.  
  778.   struct arp_tab *arp;
  779.   struct mbuf *nbp;
  780.  
  781.   dump(iface, IF_TRACE_OUT, iface->type, bp);
  782.   iface->rawsndcnt++;
  783.   iface->lastsent = secclock();
  784.   if (!(arp = arp_lookup(ARP_NETROM, gateway))) {
  785.     free_p(bp);
  786.     return (-1);
  787.   }
  788.   if (!(nbp = pushdown(bp, 5))) {
  789.     free_p(bp);
  790.     return (-1);
  791.   }
  792.   bp = nbp;
  793.   bp->data[0] = NRPROTO_IP;
  794.   bp->data[1] = NRPROTO_IP;
  795.   bp->data[2] = 0;
  796.   bp->data[3] = 0;
  797.   bp->data[4] = 0;
  798.   if (iface->trace & IF_TRACE_RAW)
  799.     raw_dump(iface, -1, bp);
  800.   send_l3_packet(Mycall, arp->hw_addr, nr_ttlinit, bp);
  801.   return 0;
  802. }
  803.  
  804. /*---------------------------------------------------------------------------*/
  805.  
  806. void nr3_input(bp, fromcall)
  807. struct mbuf *bp;
  808. char  *fromcall;
  809. {
  810.   if (bp && bp->cnt && uchar(*bp->data) == 0xff)
  811.     broadcast_recv(bp, nodeptr(fromcall, 1));
  812.   else
  813.     route_packet(bp, nodeptr(fromcall, 1));
  814. }
  815.  
  816. /*---------------------------------------------------------------------------*/
  817.  
  818. static void routing_manager_initialize()
  819. {
  820.   broadcast_timer.func = (void (*) __ARGS((void *))) send_broadcast;
  821.   set_timer(&broadcast_timer, 10 * 1000L);
  822.   start_timer(&broadcast_timer);
  823. }
  824.  
  825. /*---------------------------------------------------------------------------*/
  826. /****************************** Circuit Manager ******************************/
  827. /*---------------------------------------------------------------------------*/
  828.  
  829. #include "netrom.h"
  830.  
  831. static char  *nrreasons[] = {
  832.   "Normal",
  833.   "Reset",
  834.   "Timeout",
  835.   "Network"
  836. };
  837.  
  838. static int  server_enabled;
  839. static struct circuit *circuits;
  840.  
  841. /*---------------------------------------------------------------------------*/
  842.  
  843. char  *nr_addr2str(pc)
  844. struct circuit *pc;
  845. {
  846.  
  847.   char  *p;
  848.   static char  buf[128];
  849.  
  850.   pax25(p = buf, pc->cuser);
  851.   while (*p) p++;
  852.   *p++ = ' ';
  853.   if (pc->outbound) {
  854.     *p++ = '-';
  855.     *p++ = '>';
  856.   } else
  857.     *p++ = '@';
  858.   *p++ = ' ';
  859.   pax25(p, pc->node);
  860.   return buf;
  861. }
  862.  
  863. /*---------------------------------------------------------------------------*/
  864.  
  865. static void reset_t1(pc)
  866. struct circuit *pc;
  867. {
  868.   int32 tmp;
  869.  
  870.   tmp = pc->srtt + 4 * pc->mdev;
  871.   if (tmp < 500) tmp = 500;
  872.   set_timer(&pc->timer_t1, tmp);
  873. }
  874.  
  875. /*---------------------------------------------------------------------------*/
  876.  
  877. static void inc_t1(pc)
  878. struct circuit *pc;
  879. {
  880.   int32 tmp;
  881.  
  882.   tmp = (dur_timer(&pc->timer_t1) * 5 + 2) / 4;
  883.   if (tmp > 10 * pc->srtt) tmp = 10 * pc->srtt;
  884.   if (tmp < 500) tmp = 500;
  885.   set_timer(&pc->timer_t1, tmp);
  886. }
  887.  
  888. /*---------------------------------------------------------------------------*/
  889.  
  890. static int  busy(pc)
  891. struct circuit *pc;
  892. {
  893.   return pc->rcvcnt >= nr_tnoackbuf * NR4MAXINFO;
  894. }
  895.  
  896. /*---------------------------------------------------------------------------*/
  897.  
  898. static void send_l4_packet(pc, opcode, data)
  899. struct circuit *pc;
  900. int  opcode;
  901. struct mbuf *data;
  902. {
  903.  
  904.   int  start_t1_timer = 0;
  905.   struct mbuf *bp;
  906.  
  907.   switch (opcode & NR4OPCODE) {
  908.   case NR4OPCONRQ:
  909.     if (!(bp = pushdown(data, 20))) {
  910.       free_p(data);
  911.       return;
  912.     }
  913.     bp->data[0] = pc->localindex;
  914.     bp->data[1] = pc->localid;
  915.     bp->data[2] = 0;
  916.     bp->data[3] = 0;
  917.     bp->data[4] = opcode;
  918.     bp->data[5] = pc->window;
  919.     addrcp(bp->data + 6, pc->cuser);
  920.     addrcp(bp->data + 13, Mycall);
  921.     start_t1_timer = 1;
  922.     break;
  923.   case NR4OPCONAK:
  924.     if (!(bp = pushdown(data, 6))) {
  925.       free_p(data);
  926.       return;
  927.     }
  928.     bp->data[0] = pc->remoteindex;
  929.     bp->data[1] = pc->remoteid;
  930.     bp->data[2] = pc->localindex;
  931.     bp->data[3] = pc->localid;
  932.     bp->data[4] = opcode;
  933.     bp->data[5] = pc->window;
  934.     break;
  935.   case NR4OPDISRQ:
  936.     start_t1_timer = 1;
  937.   case NR4OPDISAK:
  938.     if (!(bp = pushdown(data, 5))) {
  939.       free_p(data);
  940.       return;
  941.     }
  942.     bp->data[0] = pc->remoteindex;
  943.     bp->data[1] = pc->remoteid;
  944.     bp->data[2] = 0;
  945.     bp->data[3] = 0;
  946.     bp->data[4] = opcode;
  947.     break;
  948.   case NR4OPINFO:
  949.     start_t1_timer = 1;
  950.   case NR4OPACK:
  951.     if (!(bp = pushdown(data, 5))) {
  952.       free_p(data);
  953.       return;
  954.     }
  955.     if (pc->reseq && !pc->naksent) {
  956.       opcode |= NR4NAK;
  957.       pc->naksent = 1;
  958.     }
  959.     if (pc->chokesent = busy(pc)) opcode |= NR4CHOKE;
  960.     stop_timer(&pc->timer_t2);
  961.     bp->data[0] = pc->remoteindex;
  962.     bp->data[1] = pc->remoteid;
  963.     bp->data[2] = pc->send_state;
  964.     bp->data[3] = pc->recv_state;
  965.     bp->data[4] = opcode;
  966.     if ((opcode & NR4OPCODE) == NR4OPINFO)
  967.       pc->send_state = uchar(pc->send_state + 1);
  968.     break;
  969.   }
  970.   if (start_t1_timer) start_timer(&pc->timer_t1);
  971.   send_l3_packet(Mycall, pc->node, nr_ttlinit, bp);
  972. }
  973.  
  974. /*---------------------------------------------------------------------------*/
  975.  
  976. static void try_send(pc, fill_sndq)
  977. struct circuit *pc;
  978. int  fill_sndq;
  979. {
  980.  
  981.   int  cnt;
  982.   struct mbuf *bp;
  983.  
  984.   stop_timer(&pc->timer_t5);
  985.   while (pc->unack < pc->cwind) {
  986.     if (pc->state != CONNECTED || pc->remote_busy) return;
  987.     if (fill_sndq && pc->t_upcall) {
  988.       cnt = space_nr(pc);
  989.       if (cnt > 0) {
  990.     (*pc->t_upcall)(pc, cnt);
  991.     if (pc->unack >= pc->cwind) return;
  992.       }
  993.     }
  994.     if (!pc->sndq) return;
  995.     cnt = len_p(pc->sndq);
  996.     if (cnt < NR4MAXINFO) {
  997.       if (pc->unack) return;
  998.       if (pc->sndqtime + 1000 - msclock() > 0) {
  999.     set_timer(&pc->timer_t5, pc->sndqtime + 1000 - msclock());
  1000.     start_timer(&pc->timer_t5);
  1001.     return;
  1002.       }
  1003.     }
  1004.     if (cnt > NR4MAXINFO) cnt = NR4MAXINFO;
  1005.     if (!(bp = alloc_mbuf(cnt))) return;
  1006.     pullup(&pc->sndq, bp->data, bp->cnt = cnt);
  1007.     enqueue(&pc->resndq, bp);
  1008.     pc->unack++;
  1009.     pc->sndtime[pc->send_state] = msclock();
  1010.     dup_p(&bp, bp, 0, cnt);
  1011.     send_l4_packet(pc, NR4OPINFO, bp);
  1012.   }
  1013. }
  1014.  
  1015. /*---------------------------------------------------------------------------*/
  1016.  
  1017. static void set_circuit_state(pc, newstate)
  1018. struct circuit *pc;
  1019. int  newstate;
  1020. {
  1021.   int  oldstate;
  1022.  
  1023.   oldstate = pc->state;
  1024.   pc->state = newstate;
  1025.   pc->retry = 0;
  1026.   stop_timer(&pc->timer_t1);
  1027.   stop_timer(&pc->timer_t2);
  1028.   stop_timer(&pc->timer_t4);
  1029.   stop_timer(&pc->timer_t5);
  1030.   reset_t1(pc);
  1031.   switch (newstate) {
  1032.   case DISCONNECTED:
  1033.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1034.     break;
  1035.   case CONNECTING:
  1036.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1037.     send_l4_packet(pc, NR4OPCONRQ, NULLBUF);
  1038.     break;
  1039.   case CONNECTED:
  1040.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1041.     try_send(pc, 1);
  1042.     break;
  1043.   case DISCONNECTING:
  1044.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1045.     send_l4_packet(pc, NR4OPDISRQ, NULLBUF);
  1046.     break;
  1047.   }
  1048. }
  1049.  
  1050. /*---------------------------------------------------------------------------*/
  1051.  
  1052. static void l4_t1_timeout(pc)
  1053. struct circuit *pc;
  1054. {
  1055.   struct mbuf *bp, *qp;
  1056.  
  1057.   inc_t1(pc);
  1058.   pc->cwind = 1;
  1059.   if (++pc->retry > nr_tretry) pc->reason = TIMEOUT;
  1060.   switch (pc->state) {
  1061.   case DISCONNECTED:
  1062.     break;
  1063.   case CONNECTING:
  1064.     if (pc->retry > nr_tretry)
  1065.       set_circuit_state(pc, DISCONNECTED);
  1066.     else
  1067.       send_l4_packet(pc, NR4OPCONRQ, NULLBUF);
  1068.     break;
  1069.   case CONNECTED:
  1070.     if (pc->retry > nr_tretry)
  1071.       set_circuit_state(pc, DISCONNECTING);
  1072.     else if (pc->unack) {
  1073.       pc->send_state = uchar(pc->send_state - pc->unack);
  1074.       for (qp = pc->resndq; qp; qp = qp->anext) {
  1075.     pc->sndtime[pc->send_state] = 0;
  1076.     dup_p(&bp, qp, 0, NR4MAXINFO);
  1077.     send_l4_packet(pc, NR4OPINFO, bp);
  1078.       }
  1079.     }
  1080.     break;
  1081.   case DISCONNECTING:
  1082.     if (pc->retry > nr_tretry)
  1083.       set_circuit_state(pc, DISCONNECTED);
  1084.     else
  1085.       send_l4_packet(pc, NR4OPDISRQ, NULLBUF);
  1086.     break;
  1087.   }
  1088. }
  1089.  
  1090. /*---------------------------------------------------------------------------*/
  1091.  
  1092. static void l4_t2_timeout(pc)
  1093. struct circuit *pc;
  1094. {
  1095.   send_l4_packet(pc, NR4OPACK, NULLBUF);
  1096. }
  1097.  
  1098. /*---------------------------------------------------------------------------*/
  1099.  
  1100. static void l4_t3_timeout(pc)
  1101. struct circuit *pc;
  1102. {
  1103.   if (!run_timer(&pc->timer_t1)) close_nr(pc);
  1104. }
  1105.  
  1106. /*---------------------------------------------------------------------------*/
  1107.  
  1108. static void l4_t4_timeout(pc)
  1109. struct circuit *pc;
  1110. {
  1111.   pc->remote_busy = 0;
  1112.   if (pc->unack) start_timer(&pc->timer_t1);
  1113.   try_send(pc, 1);
  1114. }
  1115.  
  1116. /*---------------------------------------------------------------------------*/
  1117.  
  1118. static void l4_t5_timeout(pc)
  1119. struct circuit *pc;
  1120. {
  1121.   try_send(pc, 1);
  1122. }
  1123.  
  1124. /*---------------------------------------------------------------------------*/
  1125.  
  1126. static struct circuit *create_circuit()
  1127. {
  1128.  
  1129.   static int  nextid;
  1130.   struct circuit *pc;
  1131.  
  1132.   pc = calloc(1, sizeof(*pc));
  1133.   nextid++;
  1134.   pc->localindex = uchar(nextid >> 8);
  1135.   pc->localid = uchar(nextid);
  1136.   pc->remoteindex = -1;
  1137.   pc->remoteid = -1;
  1138.   pc->cwind = 1;
  1139.   pc->srtt = 500L * nr_ttimeout;
  1140.   pc->mdev = pc->srtt / 4;
  1141.   reset_t1(pc);
  1142.   pc->timer_t1.func = (void (*) __ARGS((void *))) l4_t1_timeout;
  1143.   pc->timer_t1.arg = pc;
  1144.   pc->timer_t2.func = (void (*) __ARGS((void *))) l4_t2_timeout;
  1145.   pc->timer_t2.arg = pc;
  1146.   pc->timer_t3.func = (void (*) __ARGS((void *))) l4_t3_timeout;
  1147.   pc->timer_t3.arg = pc;
  1148.   pc->timer_t4.func = (void (*) __ARGS((void *))) l4_t4_timeout;
  1149.   pc->timer_t4.arg = pc;
  1150.   pc->timer_t5.func = (void (*) __ARGS((void *))) l4_t5_timeout;
  1151.   pc->timer_t5.arg = pc;
  1152.   pc->next = circuits;
  1153.   return circuits = pc;
  1154. }
  1155.  
  1156. /*---------------------------------------------------------------------------*/
  1157.  
  1158. static void circuit_manager(bp)
  1159. struct mbuf *bp;
  1160. {
  1161.  
  1162.   int  nakrcvd;
  1163.   struct circuit *pc;
  1164.   struct mbuf *p;
  1165.  
  1166.   if (!bp || bp->cnt < 5) goto discard;
  1167.  
  1168.   if ((bp->data[4] & NR4OPCODE) == NR4OPCONRQ) {
  1169.     if (bp->cnt != 20) goto discard;
  1170.     for (pc = circuits; pc; pc = pc->next)
  1171.       if (pc->remoteindex == uchar(bp->data[0]) &&
  1172.       pc->remoteid == uchar(bp->data[1]) &&
  1173.       addreq(pc->cuser, bp->data + 6) &&
  1174.       addreq(pc->node, bp->data + 13)) break;
  1175.     if (!pc) {
  1176.       pc = create_circuit();
  1177.       pc->remoteindex = uchar(bp->data[0]);
  1178.       pc->remoteid = uchar(bp->data[1]);
  1179.       addrcp(pc->cuser, bp->data + 6);
  1180.       addrcp(pc->node, bp->data + 13);
  1181.       pc->r_upcall = nrserv_recv_upcall;
  1182.       pc->t_upcall = nrserv_send_upcall;
  1183.       pc->s_upcall = nrserv_state_upcall;
  1184.     }
  1185.   } else
  1186.     for (pc = circuits; ; pc = pc->next) {
  1187.       if (!pc) goto discard;
  1188.       if (pc->localindex == uchar(bp->data[0]) &&
  1189.       pc->localid == uchar(bp->data[1])) break;
  1190.     }
  1191.  
  1192.   set_timer(&pc->timer_t3, nr_timeout * 1000L);
  1193.   start_timer(&pc->timer_t3);
  1194.  
  1195.   switch (bp->data[4] & NR4OPCODE) {
  1196.  
  1197.   case NR4OPCONRQ:
  1198.     switch (pc->state) {
  1199.     case DISCONNECTED:
  1200.       pc->window = uchar(bp->data[5]);
  1201.       if (pc->window > nr_twindow) pc->window = nr_twindow;
  1202.       if (pc->window < 1) pc->window = 1;
  1203.       if (server_enabled) {
  1204.     send_l4_packet(pc, NR4OPCONAK, NULLBUF);
  1205.     set_circuit_state(pc, CONNECTED);
  1206.       } else {
  1207.     send_l4_packet(pc, NR4OPCONAK | NR4CHOKE, NULLBUF);
  1208.     del_nr(pc);
  1209.       }
  1210.       break;
  1211.     case CONNECTED:
  1212.       send_l4_packet(pc, NR4OPCONAK, NULLBUF);
  1213.       break;
  1214.     default:
  1215.       goto discard;
  1216.     }
  1217.     break;
  1218.  
  1219.   case NR4OPCONAK:
  1220.     if (pc->state != CONNECTING) goto discard;
  1221.     pc->remoteindex = uchar(bp->data[2]);
  1222.     pc->remoteid = uchar(bp->data[3]);
  1223.     if (pc->window > uchar(bp->data[5])) pc->window = uchar(bp->data[5]);
  1224.     if (pc->window < 1) pc->window = 1;
  1225.     if (bp->data[4] & NR4CHOKE) {
  1226.       pc->reason = RESET;
  1227.       set_circuit_state(pc, DISCONNECTED);
  1228.     } else
  1229.       set_circuit_state(pc, CONNECTED);
  1230.     break;
  1231.  
  1232.   case NR4OPDISRQ:
  1233.     send_l4_packet(pc, NR4OPDISAK, NULLBUF);
  1234.     set_circuit_state(pc, DISCONNECTED);
  1235.     break;
  1236.  
  1237.   case NR4OPDISAK:
  1238.     if (pc->state != DISCONNECTING) goto discard;
  1239.     set_circuit_state(pc, DISCONNECTED);
  1240.     break;
  1241.  
  1242.   case NR4OPINFO:
  1243.   case NR4OPACK:
  1244.     if (pc->state != CONNECTED) goto discard;
  1245.     stop_timer(&pc->timer_t1);
  1246.     if (bp->data[4] & NR4CHOKE) {
  1247.       if (!pc->remote_busy) pc->remote_busy = msclock();
  1248.       set_timer(&pc->timer_t4, nr_tbsydelay * 1000L);
  1249.       start_timer(&pc->timer_t4);
  1250.       pc->cwind = 1;
  1251.     } else {
  1252.       pc->remote_busy = 0;
  1253.       stop_timer(&pc->timer_t4);
  1254.     }
  1255.     if (uchar(pc->send_state - bp->data[3]) < pc->unack) {
  1256.       pc->retry = 0;
  1257.       if (pc->sndtime[uchar(bp->data[3]-1)]) {
  1258.     int32 rtt = msclock() - pc->sndtime[uchar(bp->data[3]-1)];
  1259.     int32 abserr = (rtt > pc->srtt) ? rtt - pc->srtt : pc->srtt - rtt;
  1260.     pc->srtt = ((AGAIN - 1) * pc->srtt + rtt + (AGAIN / 2)) / AGAIN;
  1261.     pc->mdev = ((DGAIN - 1) * pc->mdev + abserr + (DGAIN / 2)) / DGAIN;
  1262.     reset_t1(pc);
  1263.     if (pc->cwind < pc->window && !pc->remote_busy) {
  1264.       pc->mdev += ((pc->srtt / pc->cwind + 2) / 4);
  1265.       pc->cwind++;
  1266.     }
  1267.       }
  1268.       while (uchar(pc->send_state - bp->data[3]) < pc->unack) {
  1269.     pc->resndq = free_p(pc->resndq);
  1270.     pc->unack--;
  1271.       }
  1272.     }
  1273.     nakrcvd = bp->data[4] & NR4NAK;
  1274.     if ((bp->data[4] & NR4OPCODE) == NR4OPINFO) {
  1275.       set_timer(&pc->timer_t2, nr_tackdelay);
  1276.       start_timer(&pc->timer_t2);
  1277.       if (uchar(bp->data[2] - pc->recv_state) < pc->window) {
  1278.     if (!pc->reseq || (bp->data[2] - pc->reseq->data[2]) & 0x80) {
  1279.       bp->anext = pc->reseq;
  1280.       pc->reseq = bp;
  1281.       bp = NULLBUF;
  1282.     } else {
  1283.       for (p = pc->reseq;
  1284.            p->next && (p->data[2] - bp->data[2] - 1) & 0x80;
  1285.            p = p->anext) ;
  1286.       if (p->data[2] != bp->data[2]) {
  1287.         bp->anext = p->anext;
  1288.         p->anext = bp;
  1289.         bp = NULLBUF;
  1290.       }
  1291.     }
  1292.     while (pc->reseq && !uchar(pc->reseq->data[2] - pc->recv_state)) {
  1293.       p = pc->reseq;
  1294.       pc->reseq = p->anext;
  1295.       p->anext = NULLBUF;
  1296.       pc->recv_state = uchar(pc->recv_state + 1);
  1297.       pullup(&p, NULLCHAR, 5);
  1298.       if (p) {
  1299.         pc->rcvcnt += len_p(p);
  1300.         append(&pc->rcvq, p);
  1301.       }
  1302.       pc->naksent = 0;
  1303.     }
  1304.     if (pc->r_upcall && pc->rcvcnt) (*pc->r_upcall)(pc, pc->rcvcnt);
  1305.       }
  1306.     }
  1307.     if (nakrcvd && pc->unack) {
  1308.       int  old_send_state;
  1309.       struct mbuf *bp1;
  1310.       old_send_state = pc->send_state;
  1311.       pc->send_state = uchar(pc->send_state - pc->unack);
  1312.       pc->sndtime[pc->send_state] = 0;
  1313.       dup_p(&bp1, pc->resndq, 0, NR4MAXINFO);
  1314.       send_l4_packet(pc, NR4OPINFO, bp1);
  1315.       pc->send_state = old_send_state;
  1316.       pc->cwind = 1;
  1317.     }
  1318.     try_send(pc, 1);
  1319.     if (pc->unack && !pc->remote_busy) start_timer(&pc->timer_t1);
  1320.     if (pc->closed && !pc->sndq && !pc->unack)
  1321.       set_circuit_state(pc, DISCONNECTING);
  1322.     break;
  1323.   }
  1324.  
  1325. discard:
  1326.   free_p(bp);
  1327. }
  1328.  
  1329. /*---------------------------------------------------------------------------*/
  1330. /********************************* User Calls ********************************/
  1331. /*---------------------------------------------------------------------------*/
  1332.  
  1333. struct circuit *open_nr(node, cuser, window, r_upcall, t_upcall, s_upcall, user)
  1334. char  *node, *cuser;
  1335. int  window;
  1336. void (*r_upcall) __ARGS((struct circuit *p, int cnt));
  1337. void (*t_upcall) __ARGS((struct circuit *p, int cnt));
  1338. void (*s_upcall) __ARGS((struct circuit *p, int oldstate, int newstate));
  1339. char  *user;
  1340. {
  1341.   struct circuit *pc;
  1342.  
  1343.   if (!isnetrom(node)) {
  1344.     Net_error = INVALID;
  1345.     return 0;
  1346.   }
  1347.   if (!cuser) cuser = Mycall;
  1348.   if (!window) window = nr_twindow;
  1349.   if (!(pc = create_circuit())) {
  1350.     Net_error = NO_MEM;
  1351.     return 0;
  1352.   }
  1353.   pc->outbound = 1;
  1354.   addrcp(pc->node, node);
  1355.   addrcp(pc->cuser, cuser);
  1356.   pc->window = window;
  1357.   pc->r_upcall = r_upcall;
  1358.   pc->t_upcall = t_upcall;
  1359.   pc->s_upcall = s_upcall;
  1360.   pc->user = user;
  1361.   set_circuit_state(pc, CONNECTING);
  1362.   return pc;
  1363. }
  1364.  
  1365. /*---------------------------------------------------------------------------*/
  1366.  
  1367. int  send_nr(pc, bp)
  1368. struct circuit *pc;
  1369. struct mbuf *bp;
  1370. {
  1371.   int cnt;
  1372.  
  1373.   if (!(pc && bp)) {
  1374.     free_p(bp);
  1375.     Net_error = INVALID;
  1376.     return (-1);
  1377.   }
  1378.   switch (pc->state) {
  1379.   case DISCONNECTED:
  1380.     free_p(bp);
  1381.     Net_error = NO_CONN;
  1382.     return (-1);
  1383.   case CONNECTING:
  1384.   case CONNECTED:
  1385.     if (!pc->closed) {
  1386.       if (cnt = len_p(bp)) {
  1387.     append(&pc->sndq, bp);
  1388.     pc->sndqtime = msclock();
  1389.     try_send(pc, 0);
  1390.       }
  1391.       return cnt;
  1392.     }
  1393.   case DISCONNECTING:
  1394.     free_p(bp);
  1395.     Net_error = CON_CLOS;
  1396.     return (-1);
  1397.   }
  1398.   return (-1);
  1399. }
  1400.  
  1401. /*---------------------------------------------------------------------------*/
  1402.  
  1403. int  space_nr(pc)
  1404. struct circuit *pc;
  1405. {
  1406.   int  cnt;
  1407.  
  1408.   if (!pc) {
  1409.     Net_error = INVALID;
  1410.     return (-1);
  1411.   }
  1412.   switch (pc->state) {
  1413.   case DISCONNECTED:
  1414.     Net_error = NO_CONN;
  1415.     return (-1);
  1416.   case CONNECTING:
  1417.   case CONNECTED:
  1418.     if (!pc->closed) {
  1419.       cnt = (pc->cwind - pc->unack) * NR4MAXINFO - len_p(pc->sndq);
  1420.       return (cnt > 0) ? cnt : 0;
  1421.     }
  1422.   case DISCONNECTING:
  1423.     Net_error = CON_CLOS;
  1424.     return (-1);
  1425.   }
  1426.   return (-1);
  1427. }
  1428.  
  1429. /*---------------------------------------------------------------------------*/
  1430.  
  1431. int  recv_nr(pc, bpp, cnt)
  1432. struct circuit *pc;
  1433. struct mbuf **bpp;
  1434. int cnt;
  1435. {
  1436.   if (!(pc && bpp)) {
  1437.     Net_error = INVALID;
  1438.     return (-1);
  1439.   }
  1440.   if (pc->rcvcnt) {
  1441.     if (!cnt || pc->rcvcnt <= cnt) {
  1442.       *bpp = dequeue(&pc->rcvq);
  1443.       cnt = len_p(*bpp);
  1444.     } else {
  1445.       if (!(*bpp = alloc_mbuf(cnt))) {
  1446.     Net_error = NO_MEM;
  1447.     return (-1);
  1448.       }
  1449.       pullup(&pc->rcvq, (*bpp)->data, cnt);
  1450.       (*bpp)->cnt = cnt;
  1451.     }
  1452.     pc->rcvcnt -= cnt;
  1453.     if (pc->chokesent && !busy(pc)) {
  1454.       set_timer(&pc->timer_t2, nr_tackdelay);
  1455.       start_timer(&pc->timer_t2);
  1456.     }
  1457.     return cnt;
  1458.   }
  1459.   switch (pc->state) {
  1460.   case CONNECTING:
  1461.   case CONNECTED:
  1462.     *bpp = NULLBUF;
  1463.     Net_error = WOULDBLK;
  1464.     return (-1);
  1465.   case DISCONNECTED:
  1466.   case DISCONNECTING:
  1467.     *bpp = NULLBUF;
  1468.     return 0;
  1469.   }
  1470.   return (-1);
  1471. }
  1472.  
  1473. /*---------------------------------------------------------------------------*/
  1474.  
  1475. int  close_nr(pc)
  1476. struct circuit *pc;
  1477. {
  1478.   if (!pc) {
  1479.     Net_error = INVALID;
  1480.     return (-1);
  1481.   }
  1482.   if (pc->closed) {
  1483.     Net_error = CON_CLOS;
  1484.     return (-1);
  1485.   }
  1486.   pc->closed = 1;
  1487.   switch (pc->state) {
  1488.   case DISCONNECTED:
  1489.     Net_error = NO_CONN;
  1490.     return (-1);
  1491.   case CONNECTING:
  1492.     set_circuit_state(pc, DISCONNECTED);
  1493.     return 0;
  1494.   case CONNECTED:
  1495.     if (!pc->sndq && !pc->unack) set_circuit_state(pc, DISCONNECTING);
  1496.     return 0;
  1497.   case DISCONNECTING:
  1498.     Net_error = CON_CLOS;
  1499.     return (-1);
  1500.   }
  1501.   return (-1);
  1502. }
  1503.  
  1504. /*---------------------------------------------------------------------------*/
  1505.  
  1506. int  reset_nr(pc)
  1507. struct circuit *pc;
  1508. {
  1509.   if (!pc) {
  1510.     Net_error = INVALID;
  1511.     return (-1);
  1512.   }
  1513.   pc->reason = RESET;
  1514.   set_circuit_state(pc, DISCONNECTED);
  1515.   return 0;
  1516. }
  1517.  
  1518. /*---------------------------------------------------------------------------*/
  1519.  
  1520. int  del_nr(pc)
  1521. struct circuit *pc;
  1522. {
  1523.   struct circuit *p, *q;
  1524.  
  1525.   for (q = 0, p = circuits; p != pc; q = p, p = p->next)
  1526.     if (!p) {
  1527.       Net_error = INVALID;
  1528.       return (-1);
  1529.     }
  1530.   if (q)
  1531.     q->next = p->next;
  1532.   else
  1533.     circuits = p->next;
  1534.   stop_timer(&pc->timer_t1);
  1535.   stop_timer(&pc->timer_t2);
  1536.   stop_timer(&pc->timer_t3);
  1537.   stop_timer(&pc->timer_t4);
  1538.   stop_timer(&pc->timer_t5);
  1539.   free_q(&pc->reseq);
  1540.   free_q(&pc->rcvq);
  1541.   free_q(&pc->sndq);
  1542.   free_q(&pc->resndq);
  1543.   free(pc);
  1544.   return 0;
  1545. }
  1546.  
  1547. /*---------------------------------------------------------------------------*/
  1548.  
  1549. int  valid_nr(pc)
  1550. struct circuit *pc;
  1551. {
  1552.   struct circuit *p;
  1553.  
  1554.   if (!pc) return 0;
  1555.   for (p = circuits; p; p = p->next)
  1556.     if (p == pc) return 1;
  1557.   return 0;
  1558. }
  1559.  
  1560. /*---------------------------------------------------------------------------*/
  1561.  
  1562. /* Force a retransmission */
  1563.  
  1564. int  kick_nr(pc)
  1565. struct circuit *pc;
  1566. {
  1567.   if (!valid_nr(pc)) return -1;
  1568.   l4_t1_timeout(pc);
  1569.   return 0;
  1570. }
  1571.  
  1572. /*---------------------------------------------------------------------------*/
  1573. /******************************** Login Server *******************************/
  1574. /*---------------------------------------------------------------------------*/
  1575.  
  1576. #include "login.h"
  1577.  
  1578. /*---------------------------------------------------------------------------*/
  1579.  
  1580. static void nrserv_recv_upcall(pc, cnt)
  1581. struct circuit *pc;
  1582. int  cnt;
  1583. {
  1584.   struct mbuf *bp;
  1585.  
  1586.   recv_nr(pc, &bp, 0);
  1587.   login_write((struct login_cb *) pc->user, bp);
  1588. }
  1589.  
  1590. /*---------------------------------------------------------------------------*/
  1591.  
  1592. static void nrserv_send_upcall(pc, cnt)
  1593. struct circuit *pc;
  1594. int  cnt;
  1595. {
  1596.   struct mbuf *bp;
  1597.  
  1598.   if (bp = login_read((struct login_cb *) pc->user, space_nr(pc)))
  1599.     send_nr(pc, bp);
  1600. }
  1601.  
  1602. /*---------------------------------------------------------------------------*/
  1603.  
  1604. static void nrserv_state_upcall(pc, oldstate, newstate)
  1605. struct circuit *pc;
  1606. int  oldstate, newstate;
  1607. {
  1608.   switch (newstate) {
  1609.   case CONNECTED:
  1610.     pc->user = (char *) login_open(nr_addr2str(pc), "NETROM", (void (*)()) nrserv_send_upcall, (void (*)()) close_nr, pc);
  1611.     if (!pc->user) close_nr(pc);
  1612.     break;
  1613.   case DISCONNECTED:
  1614.     login_close((struct login_cb *) pc->user);
  1615.     del_nr(pc);
  1616.     break;
  1617.   }
  1618. }
  1619.  
  1620. /*---------------------------------------------------------------------------*/
  1621. /*********************************** Client **********************************/
  1622. /*---------------------------------------------------------------------------*/
  1623.  
  1624. #include "session.h"
  1625.  
  1626. /*---------------------------------------------------------------------------*/
  1627.  
  1628. static void nrclient_parse(buf, n)
  1629. char *buf;
  1630. int n;
  1631. {
  1632.   if (!(Current && Current->type == NRSESSION && Current->cb.netrom)) return;
  1633.   if (n >= 1 && buf[n-1] == '\n') n--;
  1634.   if (!n) return;
  1635.   send_nr(Current->cb.netrom, qdata(buf, n));
  1636.   if (Current->record) {
  1637.     if (buf[n-1] == '\r') buf[n-1] = '\n';
  1638.     fwrite(buf, 1, n, Current->record);
  1639.   }
  1640. }
  1641.  
  1642. /*---------------------------------------------------------------------------*/
  1643.  
  1644. void nrclient_send_upcall(pc, cnt)
  1645. struct circuit *pc;
  1646. int  cnt;
  1647. {
  1648.  
  1649.   char  *p;
  1650.   int  chr;
  1651.   struct mbuf *bp;
  1652.   struct session *s;
  1653.  
  1654.   if (!(s = (struct session *) pc->user) || !s->upload || cnt <= 0) return;
  1655.   if (!(bp = alloc_mbuf(cnt))) return;
  1656.   p = bp->data;
  1657.   while (cnt) {
  1658.     if ((chr = getc(s->upload)) == EOF) break;
  1659.     if (chr == '\n') chr = '\r';
  1660.     *p++ = chr;
  1661.     cnt--;
  1662.   }
  1663.   if (bp->cnt = p - bp->data)
  1664.     send_nr(pc, bp);
  1665.   else
  1666.     free_p(bp);
  1667.   if (cnt) {
  1668.     fclose(s->upload);
  1669.     s->upload = 0;
  1670.     free(s->ufile);
  1671.     s->ufile = 0;
  1672.   }
  1673. }
  1674.  
  1675. /*---------------------------------------------------------------------------*/
  1676.  
  1677. void nrclient_recv_upcall(pc, cnt)
  1678. struct circuit *pc;
  1679. int  cnt;
  1680. {
  1681.  
  1682.   int  c;
  1683.   struct mbuf *bp;
  1684.  
  1685.   if (!(Mode == CONV_MODE && Current && Current->type == NRSESSION && Current->cb.netrom == pc)) return;
  1686.   recv_nr(pc, &bp, 0);
  1687.   while ((c = PULLCHAR(&bp)) != -1) {
  1688.     if (c == '\r') c = '\n';
  1689.     putchar(c);
  1690.     if (Current->record) putc(c, Current->record);
  1691.   }
  1692. }
  1693.  
  1694. /*---------------------------------------------------------------------------*/
  1695.  
  1696. static void nrclient_state_upcall(pc, oldstate, newstate)
  1697. struct circuit *pc;
  1698. int  oldstate, newstate;
  1699. {
  1700.   int  notify;
  1701.  
  1702.   notify = (Current && Current->type == NRSESSION && Current == (struct session *) pc->user);
  1703.   if (newstate != DISCONNECTED) {
  1704.     if (notify) printf("%s\n", ax25states[newstate]);
  1705.   } else {
  1706.     if (notify) printf("%s (%s)\n", ax25states[newstate], nrreasons[pc->reason]);
  1707.     if (pc->user) freesession((struct session *) pc->user);
  1708.     del_nr(pc);
  1709.     if (notify) cmdmode();
  1710.   }
  1711. }
  1712.  
  1713. /*---------------------------------------------------------------------------*/
  1714.  
  1715. static int  donconnect(argc, argv, p)
  1716. int  argc;
  1717. char  *argv[];
  1718. void *p;
  1719. {
  1720.  
  1721.   char  node[AXALEN], cuser[AXALEN];
  1722.   struct session *s;
  1723.  
  1724.   if (setcall(node, argv[1])) {
  1725.     printf("Invalid call \"%s\"\n", argv[1]);
  1726.     return 1;
  1727.   }
  1728.   if (!isnetrom(node)) {
  1729.     printf("Unknown node \"%s\"\n", argv[1]);
  1730.     return 1;
  1731.   }
  1732.   if (argc < 3)
  1733.     addrcp(cuser, Mycall);
  1734.   else if (setcall(cuser, argv[2])) {
  1735.     printf("Invalid call \"%s\"\n", argv[2]);
  1736.     return 1;
  1737.   }
  1738.   if (!(s = newsession())) {
  1739.     printf("Too many sessions\n");
  1740.     return 1;
  1741.   }
  1742.   Current = s;
  1743.   s->type = NRSESSION;
  1744.   s->name = NULLCHAR;
  1745.   s->cb.netrom = 0;
  1746.   s->parse = nrclient_parse;
  1747.   if (!(s->cb.netrom = open_nr(node, cuser, 0, nrclient_recv_upcall, nrclient_send_upcall, nrclient_state_upcall, (char *) s))) {
  1748.     freesession(s);
  1749.     switch (Net_error) {
  1750.     case NONE:
  1751.       printf("No error\n");
  1752.       break;
  1753.     case CON_EXISTS:
  1754.       printf("Connection already exists\n");
  1755.       break;
  1756.     case NO_CONN:
  1757.       printf("Connection does not exist\n");
  1758.       break;
  1759.     case CON_CLOS:
  1760.       printf("Connection closing\n");
  1761.       break;
  1762.     case NO_MEM:
  1763.       printf("No memory\n");
  1764.       break;
  1765.     case WOULDBLK:
  1766.       printf("Would block\n");
  1767.       break;
  1768.     case NOPROTO:
  1769.       printf("Protocol or mode not supported\n");
  1770.       break;
  1771.     case INVALID:
  1772.       printf("Invalid arguments\n");
  1773.       break;
  1774.     }
  1775.     return 1;
  1776.   }
  1777.   go(argc, argv, p);
  1778.   return 0;
  1779. }
  1780.  
  1781. /*---------------------------------------------------------------------------*/
  1782. /****************************** NETROM Commands ******************************/
  1783. /*---------------------------------------------------------------------------*/
  1784.  
  1785. int nr_attach(argc, argv, p)
  1786. int argc;
  1787. char *argv[];
  1788. void *p;
  1789. {
  1790.   char *ifname = "netrom";
  1791.  
  1792.   if (Nr_iface || if_lookup(ifname) != NULLIF) {
  1793.     printf("Interface %s already exists\n", ifname);
  1794.     return (-1);
  1795.   }
  1796.   Nr_iface = callocw(1, sizeof(*Nr_iface));
  1797.   Nr_iface->addr = Ip_addr;
  1798.   Nr_iface->name = strdup(ifname);
  1799.   Nr_iface->hwaddr = mallocw(AXALEN);
  1800.   memcpy(Nr_iface->hwaddr, Mycall, AXALEN);
  1801.   Nr_iface->mtu = NR4MAXINFO;
  1802.   setencap(Nr_iface, "NETROM");
  1803.   Nr_iface->next = Ifaces;
  1804.   Ifaces = Nr_iface;
  1805.   return 0;
  1806. }
  1807.  
  1808. /*---------------------------------------------------------------------------*/
  1809.  
  1810. static int  dobroadcast(argc, argv, p)
  1811. int  argc;
  1812. char  *argv[];
  1813. void *p;
  1814. {
  1815.  
  1816.   char  *hp;
  1817.   char  tmp[AXBUF];
  1818.   int  i;
  1819.   struct broadcast *bp;
  1820.  
  1821.   if (argc < 3) {
  1822.     puts("Interface  Path");
  1823.     for (bp = broadcasts; bp; bp = bp->next) {
  1824.       printf("%-9s", bp->iface->name);
  1825.       printf("  %s", pax25(tmp, bp->iface->hwaddr));
  1826.       printf("->%s", pax25(tmp, bp->hdr.dest));
  1827.       if (bp->hdr.ndigis) {
  1828.     printf(" v");
  1829.     for (hp = bp->hdr.digis[0]; hp < bp->hdr.digis[bp->hdr.ndigis]; hp += AXALEN)
  1830.       printf(" %s", pax25(tmp, hp));
  1831.       }
  1832.       putchar('\n');
  1833.     }
  1834.     return 0;
  1835.   }
  1836.  
  1837.   bp = calloc(1, sizeof(*bp));
  1838.   if (!(bp->iface = if_lookup(argv[1]))) {
  1839.     printf("Interface \"%s\" unknown\n", argv[1]);
  1840.     free(bp);
  1841.     return 1;
  1842.   }
  1843.   if (bp->iface->output != ax_output) {
  1844.     printf("Interface \"%s\" not kiss\n", argv[1]);
  1845.     free(bp);
  1846.     return 1;
  1847.   }
  1848.   if (setcall(bp->hdr.dest, argv[2])) {
  1849.     printf("Invalid call \"%s\"\n", argv[2]);
  1850.     free(bp);
  1851.     return 1;
  1852.   }
  1853.   for (i = 3; i < argc; i++)
  1854.     if (strncmp("via", argv[i], strlen(argv[i]))) {
  1855.       if (bp->hdr.ndigis >= MAXDIGIS) {
  1856.     printf("Too many digipeaters (max %d)\n", MAXDIGIS);
  1857.     free(bp);
  1858.     return 1;
  1859.       }
  1860.       if (setcall(bp->hdr.digis[bp->hdr.ndigis++], argv[i])) {
  1861.     printf("Invalid call \"%s\"\n", argv[i]);
  1862.     free(bp);
  1863.     return 1;
  1864.       }
  1865.     }
  1866.   bp->hdr.cmdrsp = LAPB_COMMAND;
  1867.   bp->next = broadcasts;
  1868.   broadcasts = bp;
  1869.   return 0;
  1870. }
  1871.  
  1872. /*---------------------------------------------------------------------------*/
  1873.  
  1874. static int  doident(argc, argv, p)
  1875. int  argc;
  1876. char  *argv[];
  1877. void *p;
  1878. {
  1879.  
  1880.   char  *cp;
  1881.   int  i;
  1882.  
  1883.   if (argc < 2)
  1884.     printf("Ident %-6.6s\n", mynode->ident);
  1885.   else {
  1886.     for (cp = argv[1], i = 0; i < IDENTLEN; i++)
  1887.       mynode->ident[i] = *cp ? toupper(*cp++) : ' ';
  1888.   }
  1889.   return 0;
  1890. }
  1891.  
  1892. /*---------------------------------------------------------------------------*/
  1893.  
  1894. /* Force a retransmission */
  1895.  
  1896. static int  donkick(argc, argv, p)
  1897. int  argc;
  1898. char  *argv[];
  1899. void *p;
  1900. {
  1901.   struct circuit *pc;
  1902.  
  1903.   pc = (struct circuit *) ltop(htol(argv[1]));
  1904.   if (!valid_nr(pc)) {
  1905.     printf(Notval);
  1906.     return 1;
  1907.   }
  1908.   kick_nr(pc);
  1909.   return 0;
  1910. }
  1911.  
  1912. /*---------------------------------------------------------------------------*/
  1913.  
  1914. static int  dolinks(argc, argv, p)
  1915. int  argc;
  1916. char  *argv[];
  1917. void *p;
  1918. {
  1919.  
  1920.   char  buf1[20], buf2[20];
  1921.   char  call[AXALEN];
  1922.   int  quality;
  1923.   long  timestamp;
  1924.   struct link *pl;
  1925.   struct linkinfo *pi;
  1926.   struct node *pn1, *pn2;
  1927.  
  1928.   if (argc >= 2) {
  1929.     if (setcall(call, argv[1])) {
  1930.       printf("Invalid call \"%s\"\n", argv[1]);
  1931.       return 1;
  1932.     }
  1933.     if (argc > 2)
  1934.       pn1 = nodeptr(call, 1);
  1935.     else if (!(pn1 = nodeptr(call, 0))) {
  1936.       printf("Unknown node \"%s\"\n", argv[1]);
  1937.       return 1;
  1938.     }
  1939.   }
  1940.  
  1941.   if (argc <= 2) {
  1942.     printf("From       To         Level  Quality   Age\n");
  1943.     for (pn2 = nodes; pn2; pn2 = pn2->next)
  1944.       if (argc < 2 || pn1 == pn2) {
  1945.     pax25(buf1, pn2->call);
  1946.     for (pl = pn2->links; pl; pl = pl->next) {
  1947.       pax25(buf2, pl->node->call);
  1948.       if (pl->info->time != PERMANENT)
  1949.         printf("%-9s  %-9s  %5i  %7i  %4i\n", buf1, buf2, pl->info->source, pl->info->quality, secclock() - pl->info->time);
  1950.       else
  1951.         printf("%-9s  %-9s  %5i  %7i\n", buf1, buf2, pl->info->source, pl->info->quality);
  1952.     }
  1953.       }
  1954.     return 0;
  1955.   }
  1956.  
  1957.   if (argc < 4 || argc > 5) {
  1958.     printf("Usage: netrom links [<node> [<node2> <quality> [permanent]]]\n");
  1959.     return 1;
  1960.   }
  1961.  
  1962.   if (setcall(call, argv[2])) {
  1963.     printf("Invalid call \"%s\"\n", argv[2]);
  1964.     return 1;
  1965.   }
  1966.   pn2 = nodeptr(call, 1);
  1967.   if (pn1 == pn2) {
  1968.     printf("Both calls are identical\n");
  1969.     return 1;
  1970.   }
  1971.  
  1972.   quality = atoi(argv[3]);
  1973.   if (quality < 0 || quality > 255) {
  1974.     printf("Quality must be 0..255\n");
  1975.     return 1;
  1976.   }
  1977.  
  1978.   if (argc < 5)
  1979.     timestamp = secclock();
  1980.   else {
  1981.     if (strncmp(argv[4], "permanent", strlen(argv[4]))) {
  1982.       printf("Usage: netrom links [<node> [<node2> <quality> [permanent]]]\n");
  1983.       return 1;
  1984.     }
  1985.     timestamp = PERMANENT;
  1986.   }
  1987.  
  1988.   pi = linkinfoptr(pn1, pn2);
  1989.   pi->quality = quality;
  1990.   pi->source = 1;
  1991.   pi->time = timestamp;
  1992.   calculate_all();
  1993.   return 0;
  1994. }
  1995.  
  1996. /*---------------------------------------------------------------------------*/
  1997.  
  1998. static int  donodes(argc, argv, p)
  1999. int  argc;
  2000. char  *argv[];
  2001. void *p;
  2002. {
  2003.  
  2004.   char  buf1[20], buf2[20];
  2005.   char  call[AXALEN];
  2006.   struct node *pn, *pn1;
  2007.  
  2008.   if (argc >= 2) {
  2009.     if (setcall(call, argv[1])) {
  2010.       printf("Invalid call \"%s\"\n", argv[1]);
  2011.       return 1;
  2012.     }
  2013.     if (!(pn1 = nodeptr(call, 0))) {
  2014.       printf("Unknown node \"%s\"\n", argv[1]);
  2015.       return 1;
  2016.     }
  2017.   }
  2018.   printf("Node       Ident   Neighbor   Level  Quality\n");
  2019.   for (pn = nodes; pn; pn = pn->next)
  2020.     if (argc < 2 || pn == pn1) {
  2021.       pax25(buf1, pn->call);
  2022.       if (pn->neighbor)
  2023.     pax25(buf2, pn->neighbor->call);
  2024.       else
  2025.     *buf2 = '\0';
  2026.       printf("%-9s  %-6.6s  %-9s  %5i  %7i\n", buf1, pn->ident, buf2, pn->hopcnt, (int) pn->quality);
  2027.     }
  2028.   return 0;
  2029. }
  2030.  
  2031. /*---------------------------------------------------------------------------*/
  2032.  
  2033. static int  doparms(argc, argv, p)
  2034. int  argc;
  2035. char  *argv[];
  2036. void *p;
  2037. {
  2038.   int  i, j;
  2039.  
  2040.   switch (argc) {
  2041.   case 0:
  2042.   case 1:
  2043.     for (i = 1; i <= NPARMS; i++)
  2044.       printf("%s %10d\n", parms[i].text, *parms[i].valptr);
  2045.     return 0;
  2046.   case 2:
  2047.   case 3:
  2048.     i = atoi(argv[1]);
  2049.     if (i < 1 || i > NPARMS) {
  2050.       printf("parameter # must be 1..%d\n", NPARMS);
  2051.       return 1;
  2052.     }
  2053.     if (argc == 2) {
  2054.       printf("%s %10d\n", parms[i].text, *parms[i].valptr);
  2055.       return 0;
  2056.     }
  2057.     j = atoi(argv[2]);
  2058.     if (j < parms[i].minval || j > parms[i].maxval) {
  2059.       printf("parameter %d must be %d..%d\n", i, parms[i].minval, parms[i].maxval);
  2060.       return 1;
  2061.     }
  2062.     *parms[i].valptr = j;
  2063.     if (dur_timer(&broadcast_timer) != nr_bdcstint * 1000L) {
  2064.       set_timer(&broadcast_timer, nr_bdcstint * 1000L);
  2065.       start_timer(&broadcast_timer);
  2066.     }
  2067.     return 0;
  2068.   default:
  2069.     printf("Usage: netrom parms [<parm#> [<parm value>]]\n");
  2070.     return 1;
  2071.   }
  2072. }
  2073.  
  2074. /*---------------------------------------------------------------------------*/
  2075.  
  2076. static int  donreset(argc, argv, p)
  2077. int  argc;
  2078. char  *argv[];
  2079. void *p;
  2080. {
  2081.   struct circuit *pc;
  2082.  
  2083.   pc = (struct circuit *) htol(argv[1]);
  2084.   if (!valid_nr(pc)) {
  2085.     printf(Notval);
  2086.     return 1;
  2087.   }
  2088.   reset_nr(pc);
  2089.   return 0;
  2090. }
  2091.  
  2092. /*---------------------------------------------------------------------------*/
  2093.  
  2094. static int  donstatus(argc, argv, p)
  2095. int  argc;
  2096. char  *argv[];
  2097. void *p;
  2098. {
  2099.  
  2100.   int  i;
  2101.   struct circuit *pc;
  2102.   struct mbuf *bp;
  2103.  
  2104.   if (argc < 2) {
  2105.     if (!Shortstatus)
  2106.       printf("bdcsts rcvd %d bdcsts sent %d\n", routes_stat.rcvd, routes_stat.sent);
  2107.     printf("   &NRCB Rcv-Q Unack  Rt  Srtt  State          Remote socket\n");
  2108.     for (pc = circuits; pc; pc = pc->next)
  2109.       printf("%8lx %5u%c%3u/%u%c %2d %5.1f  %-13s  %s\n",
  2110.          (long) pc,
  2111.          pc->rcvcnt,
  2112.          pc->chokesent ? '*' : ' ',
  2113.          pc->unack,
  2114.          pc->cwind,
  2115.          pc->remote_busy ? '*' : ' ',
  2116.          pc->retry,
  2117.          pc->srtt / 1000.0,
  2118.          ax25states[pc->state],
  2119.          nr_addr2str(pc));
  2120.     if (server_enabled)
  2121.       printf("                                Listen (S)     *\n");
  2122.   } else {
  2123.     pc = (struct circuit *) htol(argv[1]);
  2124.     if (!valid_nr(pc)) {
  2125.       printf("Not a valid control block address\n");
  2126.       return 1;
  2127.     }
  2128.     printf("Address:      %s\n", nr_addr2str(pc));
  2129.     printf("Remote id:    %d/%d\n", pc->remoteindex, pc->remoteid);
  2130.     printf("Local id:     %d/%d\n", pc->localindex, pc->localid);
  2131.     printf("State:        %s\n", ax25states[pc->state]);
  2132.     if (pc->reason)
  2133.       printf("Reason:       %s\n", nrreasons[pc->reason]);
  2134.     printf("Window:       %d\n", pc->window);
  2135.     printf("NAKsent:      %s\n", pc->naksent ? "Yes" : "No");
  2136.     printf("CHOKEsent:    %s\n", pc->chokesent ? "Yes" : "No");
  2137.     printf("Closed:       %s\n", pc->closed ? "Yes" : "No");
  2138.     if (pc->remote_busy)
  2139.       printf("Remote_busy:  %lu ms\n", msclock() - pc->remote_busy);
  2140.     else
  2141.       printf("Remote_busy:  No\n");
  2142.     printf("CWind:        %d\n", pc->cwind);
  2143.     printf("Retry:        %d\n", pc->retry);
  2144.     printf("Srtt:         %ld ms\n", pc->srtt);
  2145.     printf("Mean dev:     %ld ms\n", pc->mdev);
  2146.     printf("Timer T1:     ");
  2147.     if (run_timer(&pc->timer_t1))
  2148.       printf("%lu", read_timer(&pc->timer_t1));
  2149.     else
  2150.       printf("stop");
  2151.     printf("/%lu ms\n", dur_timer(&pc->timer_t1));
  2152.     printf("Timer T2:     ");
  2153.     if (run_timer(&pc->timer_t2))
  2154.       printf("%lu", read_timer(&pc->timer_t2));
  2155.     else
  2156.       printf("stop");
  2157.     printf("/%lu ms\n", dur_timer(&pc->timer_t2));
  2158.     printf("Timer T3:     ");
  2159.     if (run_timer(&pc->timer_t3))
  2160.       printf("%lu", read_timer(&pc->timer_t3));
  2161.     else
  2162.       printf("stop");
  2163.     printf("/%lu ms\n", dur_timer(&pc->timer_t3));
  2164.     printf("Timer T4:     ");
  2165.     if (run_timer(&pc->timer_t4))
  2166.       printf("%lu", read_timer(&pc->timer_t4));
  2167.     else
  2168.       printf("stop");
  2169.     printf("/%lu ms\n", dur_timer(&pc->timer_t4));
  2170.     printf("Timer T5:     ");
  2171.     if (run_timer(&pc->timer_t5))
  2172.       printf("%lu", read_timer(&pc->timer_t5));
  2173.     else
  2174.       printf("stop");
  2175.     printf("/%lu ms\n", dur_timer(&pc->timer_t5));
  2176.     printf("Rcv queue:    %d\n", pc->rcvcnt);
  2177.     if (pc->reseq) {
  2178.       printf("Reassembly queue:\n");
  2179.       for (bp = pc->reseq; bp; bp = bp->anext)
  2180.     printf("              Seq %3d: %3d bytes\n", uchar(bp->data[2]), len_p(bp));
  2181.     }
  2182.     printf("Snd queue:    %d\n", len_p(pc->sndq));
  2183.     if (pc->resndq) {
  2184.       printf("Resend queue:\n");
  2185.       for (i = 0, bp = pc->resndq; bp; i++, bp = bp->anext)
  2186.     printf("              Seq %3d: %3d bytes\n",
  2187.            uchar(pc->send_state - pc->unack + i), len_p(bp));
  2188.     }
  2189.   }
  2190.   return 0;
  2191. }
  2192.  
  2193. /*---------------------------------------------------------------------------*/
  2194.  
  2195. int  donetrom(argc, argv, p)
  2196. int  argc;
  2197. char  *argv[];
  2198. void *p;
  2199. {
  2200.  
  2201.   static struct cmds netromcmds[] = {
  2202.     "broadcast",dobroadcast,0, 0, NULLCHAR,
  2203.     "connect",  donconnect, 0, 2, "netrom connect <node> [<user>]",
  2204.     "ident",    doident,    0, 0, NULLCHAR,
  2205.     "kick",     donkick,    0, 2, "netrom kick <nrcb>",
  2206.     "links",    dolinks,    0, 0, NULLCHAR,
  2207.     "nodes",    donodes,    0, 0, NULLCHAR,
  2208.     "parms",    doparms,    0, 0, NULLCHAR,
  2209.     "reset",    donreset,   0, 2, "netrom reset <nrcb>",
  2210.     "status",   donstatus,  0, 0, NULLCHAR,
  2211.     NULLCHAR,   NULLFP,     0, 0, NULLCHAR
  2212.   };
  2213.  
  2214.   return subcmd(netromcmds, argc, argv, p);
  2215. }
  2216.  
  2217. /*---------------------------------------------------------------------------*/
  2218.  
  2219. int  nr4start(argc, argv, p)
  2220. int  argc;
  2221. char  *argv[];
  2222. void *p;
  2223. {
  2224.   server_enabled = 1;
  2225.   return 0;
  2226. }
  2227.  
  2228. /*---------------------------------------------------------------------------*/
  2229.  
  2230. int  nr40(argc, argv, p)
  2231. int  argc;
  2232. char  *argv[];
  2233. void *p;
  2234. {
  2235.   server_enabled = 0;
  2236.   return 0;
  2237. }
  2238.  
  2239. /*---------------------------------------------------------------------------*/
  2240. /*---------------------------------------------------------------------------*/
  2241. /*---------------------------------------------------------------------------*/
  2242.  
  2243. void netrom_initialize()
  2244. {
  2245.   link_manager_initialize();
  2246.   routing_manager_initialize();
  2247. }
  2248.  
  2249.